FloatingX 一个灵活且强大的悬浮窗解决方案。
English Introduction
具体使用文档见这里
👏 特性支持 JetPack Compose支持 浮窗半隐藏模式支持 自定义隐藏显示动画;支持 多指触摸,精准决策触摸手势;支持 自定义是否保存历史位置及还原;支持 系统浮窗、应用内浮窗、局部浮窗;支持 越界回弹,边缘悬停,边界设置;支持 以 layout, View 的方式设置浮窗内容;支持 自定义浮窗显示位置,支持辅助定位;支持 黑名单与白名单 功能,指定页面禁止显示浮窗等;支持 kotlin 构建扩展, 及对 Java 的友好兼容;支持显示位置[强行修复],应对特殊机型(需要单独开启)支持 局部浮窗,可在ViewGroup , Fragment , Activity 中进行显示;完善的日志系统,打开即可看到不同级别的Fx运行过程,更利于发现问题👨💻 依赖方式Gradledependencies {implementation 'io.github.petterpx:floatingx:2.2.6' // system浮窗&&compose时需要导入// 记得AppHelper里调用 enableComposeSupport()implementation 'io.github.petterpx:floatingx-compose:2.2.6'}🏄♀️ 效果图全屏,activity,fragment,单view小屏展示非正常比例缩放屏幕屏幕旋转功能演示完善的日志-查看器开启日志查看器,将看到Fx整个运行轨迹,更便于发现问题以及追踪解决。同时支持自定义日志tag
AppActivityViewGroup👨🔧 使用方式全局悬浮窗管理AndroidManifest (非必须)
// 如果不使用系统浮窗可以忽略此步骤(即FxScopeType.App时可跳过)kt
FloatingX.install {setContext(context)setLayout(R.layout.item_floating) setScopeType(FxScopeType.SYSTEM_AUTO)}.show()Java
AppHelper helper = AppHelper.builder().setContext(context).setLayout(R.layout.item_floating) .setScopeType(FxScopeType.SYSTEM_AUTO).build();FloatingX.install(helper).show();局部悬浮窗管理通用创建方式kt
ScopeHelper.builder { setLayout(R.layout.item_floating)}.toControl(activity)kt && java
ScopeHelper.builder().setLayout(R.layout.item_floating).build().toControl(activity).toControl(fragment).toControl(viewgroup)对kt的扩展支持activity创建悬浮窗private val scopeFx by createFx {setLayout(R.layout.item_floating)build().toControl(this/Activity)}fragment创建悬浮窗private val activityFx by createFx {setLayout(R.layout.item_floating)build().toControl(this/Fragment)}viewGroup创建悬浮窗private val activityFx by createFx {setLayout(R.layout.item_floating)build().toControl(this/Viewgroup)}🤔 技术实现System 级别悬浮窗 基于 WindowsManager 的实现方案,全局持有一个单独的悬浮窗 View ,通过 AppLifecycle 监听 Activity 生命周期,并在相应时机 插入到 WindowManager 上 ;
App 级别悬浮窗 基于 DecorView 的的实现方案,全局持有一个单独的悬浮窗 View ,通过 AppLifecycle 监听 Activity 生命周期,并在相应时机 插入到 DecorView 上 ;
View 级别悬浮窗,基于给定的 ViewGroup ;
Fragment 级别,基于其对应的 rootView ;
Acrtivity 级别,基于 DecorView 内部的 R.id.content ;
具体如下:
具体见我的博客:源码分析 | Activity-setContentView
Ps: 为什么App级别悬浮窗 要插入到 DecorView ,而不是 R.id.content -> FrameLayout ?
插入到 DecorView 可以最大程度控制悬浮窗的自由度,即悬浮窗可以真正意义上[全屏]拖动。
插入到 content 中,其拖动范围其实为 应用视图范围 ,即摆放位置 受到 状态栏 和 底部导航栏 以及 默认的 AppBar 影响, 比如当用户隐藏了状态栏或者导航栏,相对应的视图大小会发生改变,将影响悬浮窗的位置摆放。
👍 感谢基础 悬浮窗View 的 初版实现思想 源自 EnFloatingView 的 FloatingMagnetView 实现方式,并在其之上进行了彻底的重构与演变。
对于导航栏的测量部分代码来自,wenlu,并在其之上增加了